/**
 * @RabbitListener标注在类上面时，需配合@RabbitHandler注解（标注在方法上）一起使用
 * org.springframework.amqp.core.Message 只能接收简单消息，像字符串、数字这种
 * org.springframework.messaging.Message 可以接收复杂类型，像对象
 *
 * 队列不存在时，需要创建一个队列，并且与exchange绑定
 * @RabbitListener(bindings = @QueueBinding(
 *         value = @Queue(value = "topic.n1", durable = "false", autoDelete = "true"),
 *         exchange = @Exchange(value = "topic.e", type = ExchangeTypes.TOPIC),
 *         key = "r"))
 */
package com.example.rabbitmqspringbootdemo;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;


@Component
public class Consumer {

//    @RabbitListener(queues = "springSimpleQueue")
//    public void simpleListener(String message){
//            System.out.println("[Simple]received："+message);
//    }
//    public void simpleListener(Message message, Channel channel) throws Exception {
//        System.out.println("[Simple]received：" + new String(message.getBody()));
//        try {
//            //收到这条消息，已经被我消费了，可以在队列删掉，这样以后就不会再发了。否则消息服务器以为这条消息没处理掉，后续还会再发
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        } catch (IOException e) {
//            System.out.println("出错了-----" + e.getMessage());
//        //丢弃这条消息
//        //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
//        }
//    }

    //工作模式只能在配置 acknowledge-mode: manual和prefetch: 1 时有效
    @RabbitListener(queues = "springWorkQueue")
    public void workListener1(Message message, Channel channel) {
            System.out.println("[WorkQueue Q1]received：" + new String(message.getBody()));
//            try {
//                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//            } catch (IOException e) {
//                    System.out.println("出错了-----" + e.getMessage());
//                //消息被放入死信队列，若没有配置死信队列则该消息会被丢弃
//                //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
//            }
    }

     @RabbitListener(queues = "springWorkQueue")
     public void workListener2(Message message, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag)  {
            System.out.println("[WorkQueue Q2]received：" + new String(message.getBody()));
//            try {
//                    channel.basicAck(deliveryTag, false);
//            } catch (IOException e) {
//                    System.out.println("出错了-----" + e.getMessage());
//                //消息被放入死信队列，若没有配置死信队列则该消息会被丢弃
//                //channel.basicNack(deliveryTag, false,false);
//            }
    }

    @RabbitListener(queues = "springFanoutQueue1")
    public void fanoutListener1(String message) {
        System.out.println("[Fanout Q1]received：" + message);
    }

    @RabbitListener(queues = "springFanoutQueue2")
    public void fanoutListener2(String message) {
        System.out.println("[Fanout Q2]received：" + message);
    }

    @RabbitListener(queues = "springDirectQueue1")
//    public void directListener1(Message message, Channel channel) throws Exception {
//        System.out.println("[路由模式1]received：" + new String(message.getBody()));
//        try {
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        } catch (IOException e) {
//            System.out.println("出错了-----" + e.getMessage());
//            //丢弃这条消息
//            //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
//        }
//    }
    public void directListener1(String message) {
        System.out.println("[Direct Q1]received：" + message);
    }

    @RabbitListener(queues = "springDirectQueue2")
    public void directListener2(String message) {
        System.out.println("[Direct Q2]received：" + message);
    }

    //监听邮件队列，该方式在队列被删除后会自动重建和正常工作
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue_email"),
            exchange = @Exchange(
                    value = "topic.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC
            ),
            key = {"topic.#.email.#", "email.*"}))
    public void receive_email(String msg) {
        System.out.println("[邮件服务]received：" + msg);
    }

    //监听短信队列
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue_sms"),
            exchange = @Exchange(
                    value = "topic.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC
            ),
            key = {"topic.#.sms.#"}))
    public void receive_sms(String msg) {
        System.out.println("[短信服务]received: " + msg);
    }
}
